/**
 * Copyright (c) 2016-2019  All rights reserved.
 * <p>
 *
 * <p>
 * 版权所有，侵权必究！
 */

package io.yuncheng.modules.job.task;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import io.yuncheng.modules.job.entity.ScheduleParamEntity;
import io.yuncheng.modules.sys.entity.*;
import io.yuncheng.modules.sys.entity.*;
import io.yuncheng.modules.sys.service.SubAppLogCollectService;
import io.yuncheng.modules.sys.service.SubAppLogService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 算法汇总
 * 1.查询应用
 * 2.遍历应用
 * 3.遍历时间->每个应用每天所有数据汇总出一条数据
 * 4.遍历条数->每天数据过多分页处理
 *
 * @author
 */
@Slf4j
@Component("appLogArithmeticTask")
public class AppLogArithmeticTask extends AppTask {
    @Autowired
    private SubAppLogService subAppLogService;
    @Autowired
    private SubAppLogCollectService collectService;

    @Override
    public void run(String params) {
        log.info("subAppLogArithmeticTask 定时任务正在执行，参数为：{}", params);
        ScheduleParamEntity entity = JSON.parseObject(params, ScheduleParamEntity.class);
        execute(entity);
        log.info("subAppLogArithmeticTask 定时任务执行完成");
    }

    /**
     * 单个应用的执行 开始时间结束时间作为汇总值
     */
    @Override
    public void exeApplicationSave(Map<String, Object> map, SubApplicationEntity entity, Date exeDate) {
        //查询一天的数据 mark 考虑数据量过多的情况
        Object start = map.get(START);
        List<SubAppLogEntity> subAppLogEntities = subAppLogService.queryBylogAndAppId(start, map.get(END), entity.getUniqueAppId());

        //全天算法数据汇总
        SubAppLogCollectEntity subAppLogEntity = logArithmicAdd(subAppLogEntities);
        //算法路径汇总
        logAritPathAdd(subAppLogEntities,subAppLogEntity);
        subAppLogEntity.setAppId(entity.getAppId());
        subAppLogEntity.setLogDate((Date) start);
        collectService.saveOrUpdateByAppIdLogDate(subAppLogEntity);
    }
    public List<AgentArithmeticStepCollectEntity> buildListByMap(Map<String, LongSummaryStatistics> collect){
        List<AgentArithmeticStepCollectEntity> steps = new ArrayList<>();
        collect.forEach((k, v) -> {
            AgentArithmeticStepCollectEntity entity = new AgentArithmeticStepCollectEntity();
            entity.setStepAlgo(k);
            entity.setTimeSpan(v.getSum());
            entity.setAlgoCount(v.getCount());
            steps.add(entity);
        });
        return steps;
    }
    void logAritPathAdd(List<SubAppLogEntity> subAppLogEntities,SubAppLogCollectEntity subAppLogEntity){
        Map<String, LongSummaryStatistics> collect = subAppLogEntities.stream().collect(Collectors.groupingBy(SubAppLogEntity::buildStepPath, Collectors.summarizingLong(SubAppLogEntity::getExeTime)));
        List<AgentArithmeticStepCollectEntity> steps = buildListByMap(collect);
        subAppLogEntity.setStepArithPath(JSON.toJSONString(steps));
    }
    public SubAppLogCollectEntity logArithmicAdd(List<SubAppLogEntity> subAppLogEntities) {
        SubAppLogCollectEntity appLogEntity = new SubAppLogCollectEntity();
        List<AgentArithmeticStepEntity> list = new ArrayList<>();
        subAppLogEntities.forEach(a -> sumStepList(list, a));
        Map<String, LongSummaryStatistics> count = list.stream().collect(Collectors.groupingBy(AgentArithmeticStepEntity::getStepAlgo, Collectors.summarizingLong(AgentArithmeticStepEntity::getStepTimeSpan)));
        List<AgentArithmeticStepCollectEntity> steps = buildListByMap(count);
        appLogEntity.setStepArithTime(JSON.toJSONString(steps));
        return appLogEntity;
    }

    /**
     * 累加数据
     * @param list
     * @param child
     * @return
     * @author  shouxu
     * @date  2020/11/28 18:32
     */
     void sumStepList(List<AgentArithmeticStepEntity> list, SubAppLogEntity child) {
        String steps = child.getSteps();
        if (steps != null) {
            List<AgentArithmeticStepEntity> stepEntities = JSON.parseObject(steps, new TypeReference<List<AgentArithmeticStepEntity>>() {
            });
            list.addAll(stepEntities);
        }
    }
}
